package controllers

import config.{MyAwait, MyRow}
import dao._
import javax.inject.Inject
import play.api.libs.json.Json
import play.api.mvc.{AbstractController, ControllerComponents}
import utils.TableUtils
import utils.TableUtils.pageForm

import scala.concurrent.ExecutionContext

class BrowseController @Inject()(csDao: CsDao,
                                 cmDao: CmDao,
                                 genomeDao: GenomeDao,
                                 epigDao: EpigDao,
                                 snpDao: SnpDao,
                                 qtlDao: QtlDao,
                                 cc: ControllerComponents)
                                (implicit exec: ExecutionContext) extends AbstractController(cc) with MyAwait with MyRow{

  def browsePage = Action { implicit request =>
    Ok(views.html.browse.browsePage())
  }

  def getAllGenome = Action { implicit request =>
    val page = pageForm.bindFromRequest.get
    val data = TableUtils.genome
    val orderX = TableUtils.dealMapDataByPage(data, page)
    val total = orderX.size
    val tmpX = orderX.slice(page.offset, page.offset + page.limit)
    val geneids = csDao.getByGeneIds(tmpX.map(_ ("geneid"))).toAwait.map(r => r.geneid -> r).toMap

    val tmp = tmpX.map { x =>
      val species = x("species")
      if (species == "Cucumber") {
        val r = geneids(x("geneid"))
        val qtls = qtlDao.getByPos(r.chr.drop(3), r.start, r.end).toAwait.map { y =>
          s"<a href='/capdb/tools/qtlInfoPage?id=${y.id}' target='_blank'>${y.qtlId}</a>"
        }
        val qtl = if (qtls.nonEmpty) qtls.mkString(",") else "no"

        x ++ Map("qtl" -> qtl)
      } else {
        x ++ Map("qtl" -> "no")
      }
    }

    Ok(Json.obj("rows" -> tmp, "total" -> total))
  }

  def geneInfoPage(id: Int) = Action.async { implicit request =>
    genomeDao.getById(id).flatMap { x =>
      val info = x.species match{
        case "Cucumber" => csDao.getByGeneId(x.geneid).toAwait.getMapByT()
        case "Pumpkin" => cmDao.getByGeneId(x.geneid).toAwait.getMapByT()
      }
      epigDao.getByGeneId(x.geneid).flatMap { y =>
        snpDao.getByGeneId(x.geneid).map { z =>
          Ok(views.html.browse.geneInfoPage(Option(x), x.geneid,info, y, z))
        }
      }
    }
  }

  def geneInfoPageByGeneId(geneId: String) = Action.async { implicit request =>
    genomeDao.getByGeneId(geneId).flatMap { x =>
      val info = x.get.species match{
        case "Cucumber" => csDao.getByGeneId(geneId).toAwait.getMapByT()
        case "Pumpkin" => cmDao.getByGeneId(geneId).toAwait.getMapByT()
      }
      epigDao.getByGeneId(geneId).flatMap { y =>
        snpDao.getByGeneId(geneId).map { z =>
          Ok(views.html.browse.geneInfoPage(x, geneId,info, y, z))
        }
      }
    }
  }


  def getAllGene(species: String) = Action { implicit request =>
    val page = pageForm.bindFromRequest.get
    val data = species match {
      case "cs" => TableUtils.cs
      case "cm" => TableUtils.cm
    }
    val orderX = TableUtils.dealMapDataByPage(data, page)
    val total = orderX.size
    val tmpX = orderX.slice(page.offset, page.offset + page.limit)
    Ok(Json.obj("rows" -> tmpX, "total" -> total))
  }

  def csInfoPage(id: Int) = Action.async { implicit request =>
    csDao.getById(id).map { x =>
      Ok(views.html.browse.csInfoPage(x))
    }
  }

  def cmInfoPage(id: Int) = Action.async { implicit request =>
    cmDao.getById(id).map { x =>
      Ok(views.html.browse.cmInfoPage(x))
    }
  }

}
